home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 501-525 / disk_503 / pcq / pcq12a.lzh / Examples / SmallCom.p < prev    next >
Text File  |  1991-02-08  |  10KB  |  463 lines

  1. Program SmallCom;
  2.  
  3. {
  4.     This program is a simplistic terminal program, which has
  5. basically no features, but works reasonably well.  It is an ANSI
  6. compatible terminal to the extent that the console.device is - it
  7. simply passes incoming data, from the keyboard or the serial device,
  8. to the console device.
  9.  
  10.     To gain some control over the program, you might want to take a look
  11. at the translated characters (after the call to DeadKeyConvert), and
  12. process a few (function keys, for example) instead of sending them on
  13. to the console.device.
  14. }
  15.  
  16. {$I "Include:Exec/Interrupts.i"}
  17. {$I "Include:Exec/Libraries.i"}
  18. {$I "Include:Exec/Ports.i"}
  19. {$I "Include:Exec/IO.i"}
  20. {$I "Include:Exec/Devices.i"}
  21. {$I "Include:Devices/Console.i"}
  22. {$I "Include:Utils/IOUtils.i"}
  23. {$I "Include:Utils/ConsoleIO.i"}
  24. {$I "Include:Intuition/Intuition.i"}
  25. {$I "Include:Devices/InputEvent.i"}
  26. {$I "Include:Utils/DeadKeyConvert.i"}
  27. {$I "Include:Utils/BuildMenu.i"}
  28. {$I "Include:Devices/Serial.i"}
  29. {$I "Include:Exec/Memory.i"}
  30. {$I "Include:Utils/StringLib.i"}
  31.  
  32.  
  33. Type
  34.     ParityType = (no_parity, even_parity, odd_parity);
  35.  
  36. Const
  37.     w        : WindowPtr = Nil;
  38.     SerialWrite    : IOExtSerPtr = Nil;
  39.     SerialRead    : IOExtSerPtr = Nil;
  40.     ConsoleWrite : IOStdReqPtr = Nil;
  41.  
  42.     WritingConsole    : Boolean = False;
  43.     WritingSerial    : Boolean = False;
  44.  
  45.     SerialSendBuffer    : String = Nil;
  46.     ConsoleSendBuffer    : String = Nil;
  47.     SerialReceiveBuffer : String = Nil;
  48.     TranslateBuffer    : String = Nil;
  49.  
  50.     BaudRate    : Integer = 2400;
  51.     DataBits    : Byte = 8;
  52.     Parity    : ParityType = no_parity;
  53.     StopBits    : Byte = 1;
  54.     HalfDuplex    : Boolean = False;
  55.  
  56.     QuitStopDie    : Boolean = False;
  57.  
  58.     BaudRates    : Array [0..5] of Integer = (300, 1200, 2400,
  59.                          4800, 9600, 19200);
  60.  
  61. var
  62.     IMessage    : IntuiMessage;
  63.     Msg        : MessagePtr;
  64.     TitleBuffer : Array [0..79] of Char;
  65.  
  66. Procedure MakeWindowTitle;
  67. var
  68.     TitlePtr : String;
  69.     NumBuff  : Array [0..79] of Char;
  70.     Error    : Integer;
  71. begin
  72.     TitlePtr := Adr(TitleBuffer);
  73.     strcpy(TitlePtr, "SmallCom     ");
  74.     Error := IntToStr(Adr(NumBuff), BaudRate);
  75.     strcat(TitlePtr, Adr(NumBuff));
  76.     NumBuff[0] := ' ';
  77.     NumBuff[1] := Chr(DataBits + 48);
  78.     case Parity of
  79.       no_parity    : NumBuff[2] := 'N';
  80.       even_parity : NumBuff[2] := 'E';
  81.       odd_parity  : NumBuff[2] := 'O';
  82.     end;
  83.     NumBuff[3] := Chr(StopBits + 48);
  84.     NumBuff[4] := '\0';
  85.     strcat(TitlePtr, Adr(NumBuff));
  86.     SetWindowTitles(w, TitlePtr, Nil);
  87. end;
  88.  
  89. Function OpenTheWindow : Boolean;
  90. var
  91.     nw : NewWindowPtr;
  92. begin
  93.     new(nw);
  94.     with nw^ do begin
  95.     LeftEdge := 0;
  96.     TopEdge := 0;
  97.     Width := 320;
  98.     Height := 200;
  99.  
  100.     DetailPen := -1;
  101.     BlockPen  := -1;
  102.     IDCMPFlags := RAWKEY_f + MENUPICK_f + CLOSEWINDOW_f;
  103.     Flags := SMART_REFRESH + ACTIVATE + WINDOWSIZING + WINDOWDRAG +
  104.             WINDOWDEPTH + WINDOWCLOSE + SIZEBBOTTOM;
  105.     FirstGadget := Nil;
  106.     CheckMark := Nil;
  107.     Title := "";
  108.     Screen := Nil;
  109.     BitMap := Nil;
  110.     MinWidth := 0;
  111.     MaxWidth := -1;
  112.     MinHeight := 0;
  113.     MaxHeight := -1;
  114.     WType := WBENCHSCREEN_f;
  115.     end;
  116.  
  117.     w := OpenWindow(nw);
  118.     dispose(nw);
  119.     OpenTheWindow := w <> nil;
  120. end;
  121.  
  122. Procedure AddTheMenus;
  123. begin
  124.     InitializeMenu(w);
  125.     NewMenu("Project");
  126.     NewItem("Quit",'Q');
  127.     NewMenu("Serial");
  128.  
  129.     NewItem("Baud Rate",'\0');
  130.     NewSubItem("  300", '1');
  131.     NewSubItem(" 1200", '2');
  132.     NewSubItem(" 2400", '3');
  133.     NewSubItem(" 4800", '4');
  134.     NewSubItem(" 9600", '5');
  135.     NewSubItem("19200", '6');
  136.  
  137.     NewItem("Data Size", '\0');
  138.     NewSubItem("7N2", '\0');
  139.     NewSubItem("7E1", '\0');
  140.     NewSubItem("7O1", '\0');
  141.     NewSubItem("8N1", '\0');
  142.  
  143.     NewItem("Duplex   ", '\0');
  144.     NewSubItem("Half", 'H');
  145.     NewSubItem("Full", 'F');
  146.  
  147.     AttachMenu;
  148. end;
  149.  
  150.  
  151. Function CreateExtIO(ioReplyPort : MsgPortPtr; Size : Integer) : Address;
  152. var
  153.     Request : IOStdReqPtr;
  154. begin
  155.     if ioReplyPort = Nil then
  156.     CreateExtIO := Nil;
  157.  
  158.     Request := AllocMem(Size, MEMF_CLEAR + MEMF_PUBLIC);
  159.     if Request = Nil then
  160.     CreateExtIO := Nil;
  161.  
  162.     with Request^.io_Message.mn_Node do begin
  163.     ln_Type := NTMessage;
  164.     ln_Pri := 0;
  165.     end;
  166.     Request^.io_Message.mn_ReplyPort := ioReplyPort;
  167.     CreateExtIO := Request;
  168. end;
  169.  
  170.  
  171. Procedure DeleteExtIO(Request : Address; Size : Integer);
  172. var
  173.     Req : IOStdReqPtr;
  174. begin
  175.     Req := Request;
  176.     with Req^ do begin
  177.     io_Message.mn_Node.ln_Type := NodeType($FF);
  178.     io_Device := Address(-1);
  179.     io_Unit := Address(-1);
  180.     end;
  181.     FreeMem(Request, Size);
  182. end;
  183.  
  184.  
  185. Procedure Die;
  186. var
  187.     Error : Integer;
  188. begin
  189.     if SerialWrite <> Nil then begin
  190.     if CheckIO(SerialRead) = Nil then begin
  191.         Error := AbortIO(SerialRead);
  192.         Error := WaitIO(SerialRead);
  193.     end;
  194.     CloseDevice(SerialWrite);
  195.     DeleteExtIO(SerialWrite, SizeOf(IOExtSer));
  196.     if SerialRead <> Nil then
  197.         DeleteExtIO(SerialRead, SizeOf(IOExtSer));
  198.     end;
  199.  
  200.     if ConsoleWrite <> Nil then begin
  201.     CloseDevice(ConsoleWrite);
  202.     DeleteStdIO(ConsoleWrite);
  203.     end;
  204.     if w <> Nil then begin
  205.     DetachMenu;
  206.     Forbid;
  207.     while GetMsg(w^.UserPort) <> Nil do;
  208.     Permit;
  209.     CloseWindow(w);
  210.     end;
  211.     Exit(0);
  212. end;
  213.  
  214. Procedure SendSerial(IO : IOExtSerPtr; Data : Address; Size : Integer);
  215. var
  216.     Error : Short;
  217. begin
  218.     with IO^.IOSer do begin
  219.     io_Data := Data;
  220.     io_Length := Size;
  221.     io_Command := CMD_WRITE;
  222.     end;
  223.     Error := DoIO(IO);
  224. end;
  225.  
  226. Procedure QueueSerialRead;
  227. var
  228.     Waiting : Integer;
  229. begin
  230.     with SerialRead^.IOSer do begin
  231.     io_Command := SDCMD_QUERY;
  232.     Waiting := DoIO(SerialRead);
  233.     Waiting := io_Actual;
  234.     if Waiting = 0 then
  235.         Waiting := 1
  236.     else if Waiting > 80 then
  237.         Waiting := 80;
  238.     io_Length := Waiting;
  239.     io_Command := CMD_READ;
  240.     io_Data := SerialReceiveBuffer;
  241.     end;
  242.     SendIO(SerialRead);
  243. end;
  244.  
  245.  
  246. Procedure SetSerialParams;
  247. var
  248.     Error : Short;
  249. begin
  250.     with SerialWrite^ do begin
  251.     io_ReadLen    := DataBits;
  252.     io_BrkTime    := 750000;
  253.     io_Baud        := BaudRate;
  254.     io_WriteLen    := DataBits;
  255.     io_StopBits    := StopBits;
  256.     io_RBufLen    := 4000;
  257.     io_TermArray.TermArray0 := $51040303;
  258.     io_TermArray.TermArray1 := $03030303;
  259.     io_CtlChar    := SER_DEFAULT_CTLCHAR;
  260.     case parity of
  261.       no_parity    : io_SerFlags := 0;
  262.       even_parity    : io_SerFlags := SERF_PARTY_ON;
  263.       odd_parity    : io_SerFlags := SERF_PARTY_ON + SERF_PARTY_ODD;
  264.     end;
  265.     IOSer.io_Command := SDCMD_SETPARAMS;
  266.     end;
  267.     if CheckIO(SerialRead) = Nil then begin
  268.     Error := AbortIO(SerialRead);
  269.     Error := WaitIO(SerialRead);
  270.     end;
  271.     Error := DoIO(SerialWrite);
  272.     QueueSerialRead;
  273.     MakeWindowTitle;
  274. end;
  275.  
  276.  
  277. Function OpenSerialDevice : Boolean;
  278. var
  279.     Error : Short;
  280. begin
  281.     SerialWrite := CreateExtIO(w^.UserPort, SizeOf(IOExtSer));
  282.     if SerialWrite = Nil then
  283.     OpenSerialDevice := False;
  284.     SerialRead := CreateExtIO(w^.UserPort, SizeOf(IOExtSer));
  285.     if SerialWrite = Nil then begin
  286.     DeleteExtIO(SerialWrite, SizeOf(IOExtSer));
  287.     SerialWrite := Nil;
  288.     OpenSerialDevice := False;
  289.     end;
  290.  
  291.     with SerialWrite^ do begin
  292.     io_ReadLen    := DataBits;
  293.     io_BrkTime    := 750000;
  294.     io_Baud        := BaudRate;
  295.     io_WriteLen    := DataBits;
  296.     io_StopBits    := StopBits;
  297.     io_RBufLen    := 4000;
  298.     io_SerFlags    := 0;
  299.     io_SerFlags    := 0;
  300.     end;
  301.  
  302.     Error := OpenDevice("serial.device", 0, SerialWrite, 0);
  303.  
  304.     if Error = 0 then begin
  305.     SerialRead^ := SerialWrite^;
  306.     QueueSerialRead;
  307.     SetSerialParams;
  308.     OpenSerialDevice := True;
  309.     end else begin
  310.     DeleteExtIO(SerialWrite, SizeOf(IOExtSer));
  311.     DeleteExtIO(SerialRead, SizeOf(IOExtSer));
  312.     SerialWrite := Nil;
  313.     OpenSerialDevice := False;
  314.     end;
  315. end;
  316.  
  317.  
  318. Function OpenConsoleDevice : Boolean;
  319. var
  320.     Error : Short;
  321. begin
  322.     ConsoleWrite := CreateStdIO(w^.UserPort);
  323.     if ConsoleWrite = Nil then
  324.     OpenConsoleDevice := False;
  325.  
  326.     with ConsoleWrite^ do begin
  327.     io_Data := w;
  328.     io_Length := SizeOf(Window);
  329.     end;
  330.  
  331.     Error := OpenDevice("console.device", 0, ConsoleWrite, 0);
  332.     if Error = 0 then
  333.     ConsoleBase := ConsoleWrite^.io_Device
  334.     else
  335.     DeleteStdIO(ConsoleWrite);
  336.     OpenConsoleDevice := Error = 0;
  337. end;
  338.  
  339.  
  340. Procedure OpenEverything;
  341. begin
  342.     SerialSendBuffer    := AllocString(80);
  343.     ConsoleSendBuffer    := AllocString(80);
  344.     SerialReceiveBuffer := AllocString(80);
  345.     TranslateBuffer    := AllocString(80);
  346.     
  347.     if not OpenTheWindow then
  348.     Die;
  349.  
  350.     AddTheMenus;
  351.  
  352.     if not OpenConsoleDevice then
  353.     Die;
  354.  
  355.     if not OpenSerialDevice then
  356.     Die;
  357. end;
  358.  
  359.  
  360. Procedure ProcessIntuitionMsg;
  361. var
  362.     IMessage    : IntuiMessage;
  363.     IPtr    : IntuiMessagePtr;
  364.  
  365.     Procedure ProcessMenu;
  366.     var
  367.     MenuNumber    : Short;
  368.     ItemNumber    : Short;
  369.     SubItemNumber    : Short;
  370.     begin
  371.     if IMessage.Code = MENUNULL then
  372.         return;
  373.  
  374.     MenuNumber := MenuNum(IMessage.Code);
  375.     ItemNumber := ItemNum(IMessage.Code);
  376.     SubItemNumber := SubNum(IMessage.Code);
  377.  
  378.     case MenuNumber of
  379.       0 : if ItemNumber = 0 then
  380.          QuitStopDie := True;
  381.       1 : begin
  382.           case ItemNumber of
  383.             0 : BaudRate := BaudRates[SubItemNumber];
  384.             1 : case SubItemNumber of
  385.               0 : begin
  386.                   DataBits := 7;
  387.                   Parity   := no_parity;
  388.                   StopBits := 2;
  389.                   end;
  390.               1 : begin
  391.                   DataBits := 7;
  392.                   Parity   := even_parity;
  393.                   StopBits := 1;
  394.                   end;
  395.               2 : begin
  396.                   DataBits := 7;
  397.                   Parity   := odd_parity;
  398.                   StopBits := 1;
  399.                   end;
  400.               3 : begin
  401.                   DataBits := 8;
  402.                   Parity   := no_parity;
  403.                   StopBits := 1;
  404.                   end;
  405.             end;
  406.             2 : HalfDuplex := SubItemNumber = 0;
  407.           end;
  408.           if ItemNumber < 2 then
  409.               SetSerialParams;
  410.           end;
  411.     end;
  412.     end;
  413.  
  414.  
  415.     Procedure ProcessKeypress;
  416.     var
  417.     Length    : Short;
  418.     Buffer    : Array [0..79] of Char;
  419.     begin
  420.     if IMessage.Code < 128 then begin
  421.         Length := DeadKeyConvert(Adr(IMessage), TranslateBuffer, 79, Nil);
  422.         if Length > 0 then begin
  423.         if HalfDuplex then
  424.             ConWrite(ConsoleWrite, TranslateBuffer, Length);
  425.         SendSerial(SerialWrite, TranslateBuffer, Length);
  426.         end;
  427.     end;
  428.     end;
  429.  
  430. begin
  431.     IPtr := IntuiMessagePtr(Msg);
  432.     IMessage := IPtr^;
  433.     ReplyMsg(Msg);
  434.  
  435.     case IMessage.Class of
  436.       MENUPICK_f : ProcessMenu;
  437.       RAWKEY_f   : ProcessKeypress;
  438.       CLOSEWINDOW_f : QuitStopDie := True;
  439.     end;
  440. end;
  441.  
  442. Procedure ProcessSerialInput;
  443. begin
  444.     with SerialRead^.IOSer do begin
  445.     if io_Actual > 0 then
  446.         ConWrite(ConsoleWrite, SerialReceiveBuffer, io_Actual);
  447.     end;
  448.     QueueSerialRead;
  449. end;
  450.  
  451. begin
  452.     OpenEverything;
  453.     repeat
  454.     Msg := WaitPort(w^.UserPort);
  455.     Msg := GetMsg(w^.UserPort);
  456.     if Msg = MessagePtr(SerialRead) then
  457.         ProcessSerialInput
  458.     else
  459.         ProcessIntuitionMsg;
  460.     until QuitStopDie;
  461.     Die;
  462. end.
  463.